Cartography Toolbox:

Waterlining Tool and Polygon Boundary Symbology Tool

Developed by:

Andrew Gibbs, Tony Le Donne, John Cortenbach and Camille Borrowdale

All credits go to original developers unless otherwise stated.

Python Version: 3.6.1

1.0 Introduction


         The this toolbox contains two cartographically-focused tools that can be used to improve the artistic qualities of maps made within ArcGIS Pro. The tools include:

- Coastal vignettes are graphic representations of the interface between land and water. Vignettes can be utilized to depict land in a fashion that appears to gradually fade into water, representing shallow areas near shore transitioning into deepening water with a expanding sequence of corresponding shape outlines.

-The second tool, pertaining to inner/outer polygon boundary symbology simplifies the methodology with which a user can symbolize the interface boundary between adjacent shapefiles using two separate symbolized boundaries.

2.0 Toolbox Details


2.1 System and Software Requirements


Compatible Operating Systems

Compatible Software

Required Data Format

2.2 Limitations


2.3 Installing the Toolbox

2.4 Un-installing the Toolbox


3.0 Waterlining Tool


3.1  Tool Description


A tool used in ArcGIS Pro that creates multiple buffer outlines around a shapefile polygon using user-defined parameters. This tool assists in the cartographic process of creating thematic maps.

3.2 Using the Waterlining Tool


1.        Workspace: User-defined shapefile

2.        Output Feature Class: User-defined workspace of output destination

3.        Buffer Distance: User input, amount will  on geographic size of shapefile      

4.        Units: User input, dependent on shapefile

5.        Inside or Outside: User Input, dependent on user-desired symbolization.


        

The following headings and subsections pertain to the Python foundation inside the tool itself:


3.3 Imports


import arcpy # include the ArcGIS library

import sys # include the system library to access the number of parameters

import math

import os

3.4  Functions


     The waterlining functionality below is defined along with the parameters of the user-specified initial buffer distance and requested number of buffers. The output creates a series of buffers, whether inside or outside of the polygon itself, increasing exponentially with each successive buffer. In order to achieve this, we need to filter out each channel in the image using ArcGIS Pro Toolbox.

"""

* MyPrint

* Mini function to send the print messages to the right output

* Created by Jim Graham

*

* Input:

* - Message - string to be printed

*

* Output:

* - The message on either Wing Debug I/O or ArcGIS Pro Window

"""

def MyPrint(Message):

    if (len(sys.argv)>1): # if running in a tool, print into ArcGIS

        arcpy.AddMessage(Message)

    else: # else print to Debug I/O

        print(Message)

       

"""

* Vignette

* Complete buffer analysis using user-defined parameters, which creates multiple buffers, merges the buffers, and deletes the individual buffers.

*

* Input:

* - PolygonClassification - Specifies if the input feature layer is land or water, so the water lining displays on the proper side

* - InitialBufferDistance - Sets the distance to the initial buffer created, which is also the minimum distance subsequent buffers

* - NumberOfBuffers - Sets the total number of buffers to be created and then merged together

* - OutlineExpansionFactor - Value that increases the distance between buffers over iterations of buffer creations, beginning with the initial buffer distance and increasing

*

* Output:

* - A new feature layer shapefile that represents the water lining of the input feature layer.

"""

def Vignette (PolygonClassification, InitialBufferDistance, NumberOfBuffers):

    count=1

   

    # This allows us to run the script repeatedly without deleting the intermdiate files

    arcpy.env.overwriteOutput=False

       

    # Create a search cursor based on the shapefile

    SearchCursor = arcpy.SearchCursor(InputFeatureLayer)

   

    # Creates buffers outside of the input feature layer for coastal waterlining

    if (PolygonClassification == "Land"):

       

        for x in range(0, NumberOfBuffers):

            # formula to calculate intervals between lines. is negative for Arc buffering inside polygon

            distance = (InitialBufferDistance*math.exp(OutlineExpansionFactor*count)) - InitialBufferDistance

           

            # same formula as above but positive for adding to attribute table.

            distancePos = (InitialBufferDistance*math.exp(OutlineExpansionFactor*count)) - InitialBufferDistance

           

            # Creates a buffer using the InitialBufferDistance, NumberOfBuffers, and OutlineExpansionFactor parameters and the input feature layer

            arcpy.Buffer_analysis(InputFeatureLayer, "Buffer_" + OutputFeatureName + str(count) + ".shp", distance,"OUTSIDE_ONLY","ROUND","ALL")

           

            # Creates a new field with the buffer distance and calculates the value

            arcpy.AddField_management("Buffer_"+OutputFeatureName+str(count)+".shp", "bufferDist", "FLOAT")

            arcpy.CalculateField_management("Buffer_"+OutputFeatureName+str(count)+".shp", "bufferDist", distancePos, "PYTHON_9.3")

            count = count + 1

   

    # Creates buffers inside of the input feature layer for water body waterlining     

    elif (PolygonClassification == "Water"):

       

        for x in range(0, NumberOfBuffers):

            # formula to calculate intervals between lines. is negative for Arc buffering inside polygon

            distance = -(InitialBufferDistance*math.exp(OutlineExpansionFactor*count)) + InitialBufferDistance

           

            # same formula as above but positive for adding to attribute table.

            distancePos = (InitialBufferDistance*math.exp(OutlineExpansionFactor*count)) + InitialBufferDistance

           

            # Creates a buffer using the InitialBufferDistance, NumberOfBuffers, and OutlineExpansionFactor parameters and the input feature layer

            arcpy.Buffer_analysis(InputFeatureLayer, "Buffer_" + OutputFeatureName + str(count) + ".shp", distance,"OUTSIDE_ONLY","ROUND","ALL")

           

            # Creates a new field with the buffer distance and calculates the value

            arcpy.AddField_management("Buffer_"+OutputFeatureName+str(count)+".shp", "bufferDist", "FLOAT")

            arcpy.CalculateField_management("Buffer_"+OutputFeatureName+str(count)+".shp", "bufferDist", distancePos, "PYTHON_9.3")

            count = count + 1          

################################################################# end functions

# Set up variables

# Setup default parameters and then get the parameters from the argument list if we are running as a tool in ArcMap.

OutputWorkspace = "C:/temp/Vignette"

InputFeatureLayer = "C:/temp/Vignette/Lake_Tahoe_NAD83_UTM_Zone_10.shp"

OutputFeatureName = "Test"

PolygonClassification = "water"

InitialBufferDistance = 700 # in meters

NumberOfBuffers = 20

OutlineExpansionFactor = 0.1

if (len(sys.argv)>1): # if running in a tool, get the parameters from arc

    InputFeatureLayer = arcpy.GetParameterAsText(0) # input feature class

    OutputWorkspace = arcpy.GetParameterAsText(1) # working directory    

    OutputFeatureName = arcpy.GetParameterAsText(2) # string for output file name

    PolygonClassification = arcpy.GetParameterAsText(3) # string 'land' or 'water'

    InitialBufferDistance = arcpy.GetParameter(4) #long int for increments

    NumberOfBuffers = arcpy.GetParameter(5) #long int to exponentially increase for number of NumberOfBuffers

    OutlineExpansionFactor = arcpy.GetParameter(6) #double

# Print the parameters for debugging

MyPrint("InputFeatureLayer: " + InputFeatureLayer)

MyPrint("OutputWorkspace: " + OutputWorkspace)

MyPrint("OutputFeatureName: " + OutputFeatureName)

MyPrint("PolygonClassification: " + PolygonClassification)

MyPrint("InitialBufferDistance: " + format(InitialBufferDistance))

MyPrint("NumberOfBuffers: " + format(NumberOfBuffers))

MyPrint("OutlineExpansionFactor: " + format(OutlineExpansionFactor))

3.5 Main Code


# This allows us to run the script repeatedly without deleting the intermediate files

arcpy.env.overwriteOutput = False

#set Workspace

arcpy.env.workspace = OutputWorkspace

# print processing step to screen

MyPrint("Running Vignette function: Creating buffers based on PolygonClassification, InitialBufferDistance, OutlineExpansionFactor, and NumberOfBuffers...")

# runs the vignette function

Vignette(PolygonClassification, InitialBufferDistance, NumberOfBuffers)

# print processing step to screen

MyPrint("Vignette done.")

# print processing step to screen

MyPrint("Merging buffers...")

# Creates empty list to load individual buffer files

FClassesList = []

i = 0

# appends individual buffer files into the FClassesList

fcs = arcpy.ListFeatureClasses("Buffer_*")

for fc in fcs:

    FClassesList.append(fc)

    i=i+1

# merges all elements of the FClassesList list into one file

arcpy.Merge_management(FClassesList, OutputFeatureName)

# print processing step to screen

MyPrint("Merging buffers done.")

# print processing step to screen

MyPrint("Deleting individual buffer feature classes...")

# Deletes individual buffers used in vignette tool

for feature in FClassesList:

    arcpy.Delete_management(feature)

# print processing step to screen

MyPrint("Deleting individual buffer feature classes done.")

# print processing step to screen

MyPrint("Finished creating water lines!")

###################################################### end main code

4.0 Polygon Boundary Symbology Tool


4.1 Tool Description


The Polygon Boundary Symbology tool allows the user to modify the boundary outline of a polygon on either the inside or the outside of the polygon boundary.

4.2 Using the Tool


 

1.        Input Features: User-defined shapefile

2.        Output Feature Class: User-defined workspace of output destination

3.        Buffer Distance: User input; amount will vary with the geographic extent of shapefile      

4.        Units: User input, dependent on shapefile

5.        Inside or Outside: User Input; dependent upon user-desired symbolization.


        

The following headings and subsections pertain to the Python foundation inside the tool itself:


4.3 Library Imports


import arcpy # include the ArcGIS library

import sys # include the system library to access the number of parameters

4.4 Functions


def MyPrint(Message):

    if (len(sys.argv)>1): # if running in a tool, print into ArcGIS

        arcpy.AddMessage(Message)

    else: # else print to Debug I/O

        print(Message)

##################################################################

# Setup default parameters and then get the parameters from the argument

# list if we are running as a tool in ArcMap.

##################################################################

#Python script for quickly creating an inner polygon outline in ArcGIS Pro.

#Set up for use in an Arc toolbox.

 

InputPath = "C:\\temp\\lower48.shp" # define input file path

OutputPath = "C:\\temp\\lower48inside.shp" # name of output file

BufferDistance = "20 Miles" #floating point buffer distance input amount

Choice = "Inside"

if (len(sys.argv)>1): # if running in a tool, get the parameters from ArcGIS Pro

    InputPath = arcpy.GetParameterAsText(0)

    OutputPath = arcpy.GetParameterAsText(1)

    BufferDistance = arcpy.GetParameterAsText(2)

    Choice = arcpy.GetParameterAsText(3)

   

    # Print the parameters for debugging

    MyPrint("InputPath: "+InputPath)

    MyPrint("OutputPath: "+OutputPath)

   

arcpy.AddMessage("Creating polygon boundary symbology based on user inputs...")

4.4 Main Code


arcpy.env.overwriteOutput=False

if (Choice == "Inside"):

     (Notes) The first line of the above code ensures that the script can run repeatedly without overwriting intermediate files. The following line is based on if the user chooses to draw the boundary on the inside and if so, a message is printed marking the start of processing, then the next line creates a buffer based upon the user-specified shapefile and subsequently draws a stroke inside the boundary. Lastly, a message is printed to notify the user once the buffering has finished.

 

    print("Beginning processing...")

    #Complete analysis using user-defined parameters

    arcpy.analysis.Buffer(InputPath, OutputPath, "-"+BufferDistance, "OUTSIDE_ONLY", "ROUND", "NONE", None, "PLANAR")

    arcpy.AddMessage("Completed Inner Boundary Outline.")

   

elif (Choice == "Outside"):

   

    print("Beginning processing...")

    #Complete analysis using user-defined parameters

    arcpy.analysis.Buffer(InputPath, OutputPath, BufferDistance, "OUTSIDE_ONLY", "ROUND", "NONE", None, "PLANAR")    

    arcpy.AddMessage("Completed Outer Boundary Outline.")

     (Notes) The beginning of this block of code is an ‘else if’ statement that prompts the code to continue if the user chooses the ‘outside’ stroke option. Then a buffer is created just as in the previous ‘inside’ code does, but rather the stroke is drawn on the outside. Lastly, a message is printed to notify the user once the buffering has finished.

4.5 Example Applications



5.0 Troubleshooting and Contact Information

If there are any problems or concerns with this toolset, feel free to contact the following:

Contacts

Jim Graham: James.Graham@humboldt.edu

Amy Rock: Amy.Rock@humboldt.edu